package com.ruoyi.web.controller.purchase;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.purchase.domain.Offers;
import com.ruoyi.purchase.service.IOffersService;
import com.ruoyi.purchase.service.ISysGroupUserService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * offersController
 *
 * @author hmy
 * @date 2025-08-22
 */
@RestController
@RequestMapping("/purchase/offers")
public class OffersController extends BaseController
{
    @Autowired
    private IOffersService offersService;

    @Autowired
    private ISysUserService sysUserService; // 用户服务

    @Autowired
    private ISysGroupUserService sysGroupUserService; // 分组用户服务

    @Autowired
    private JavaMailSender javaMailSender; // 邮件发送服务

    @Value("${spring.mail.username}")
    private String fromEmail; // 发件人邮箱

    /**
     * 查询offers列表
     */
    @PreAuthorize("@ss.hasPermi('purchase:offers:list')")
    @GetMapping("/list")
    public TableDataInfo list(Offers offers)
    {
        startPage();
        List<Offers> list = offersService.selectOffersList(offers);
        return getDataTable(list);
    }

    /**
     * 导出offers列表
     */
    @PreAuthorize("@ss.hasPermi('purchase:offers:export')")
    @Log(title = "offers", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Offers offers)
    {
        List<Offers> list = offersService.selectOffersList(offers);
        ExcelUtil<Offers> util = new ExcelUtil<Offers>(Offers.class);
        util.exportExcel(response, list, "offers数据");
    }

    /**
     * 获取offers详细信息
     */
    @PreAuthorize("@ss.hasPermi('purchase:offers:query')")
    @GetMapping(value = "/{offerId}")
    public AjaxResult getInfo(@PathVariable("offerId") Long offerId)
    {
        return success(offersService.selectOffersByOfferId(offerId));
    }

    @PreAuthorize("@ss.hasPermi('purchase:offers:add')")
    @Log(title = "offers", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Offers offers)
    {
        // 插入offers数据
        int result = offersService.insertOffers(offers);

        if (result > 0) {
            try {
                // 只有当 notifyUsers 为 true 时才发送邮件通知
                if (offers.getNotifyUsers() != null && offers.getNotifyUsers()) {
                    sendOfferNotification(offers);
                    return AjaxResult.success("新增成功，邮件已发送");
                } else {
                    return AjaxResult.success("新增成功");
                }
            } catch (Exception e) {
                logger.error("发送邮件通知失败", e);
                return AjaxResult.success("新增成功，但邮件发送失败: " + e.getMessage());
            }
        }
        return toAjax(result);
    }

    /**
     * 修改offers
     */
    @PreAuthorize("@ss.hasPermi('purchase:offers:edit')")
    @Log(title = "offers", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Offers offers)
    {
        // 更新offers数据
        int result = offersService.updateOffers(offers);

        if (result > 0) {
            try {
                // 只有当 notifyUsers 为 true 时才发送邮件通知
                if (offers.getNotifyUsers() != null && offers.getNotifyUsers()) {
                    sendOfferNotification(offers);
                    return AjaxResult.success("修改成功，邮件已发送");
                } else {
                    return AjaxResult.success("修改成功");
                }
            } catch (Exception e) {
                logger.error("发送邮件通知失败", e);
                return AjaxResult.success("修改成功，但邮件发送失败: " + e.getMessage());
            }
        }
        return toAjax(result);
    }

    /**
     * 发送offer通知邮件
     *
     * @param offers offer信息
     */
    private void sendOfferNotification(Offers offers) {
        try {
            List<Long> userIds = new ArrayList<>();

            // 根据visibility决定发送范围
            if ("public".equals(offers.getVisibility())) {
                // public模式：发送给所有用户
                List<SysUser> allUsers = sysUserService.selectUserList(new SysUser());
                userIds = allUsers.stream()
                        .map(SysUser::getUserId)
                        .collect(Collectors.toList());
            } else if ("private".equals(offers.getVisibility())) {
                // private模式：发送给指定的用户和分组中的用户

                // 添加直接选择的用户
                if (offers.getUserIds() != null && !offers.getUserIds().isEmpty()) {
                    userIds.addAll(offers.getUserIds().stream()
                            .filter(id -> id != null)
                            .collect(Collectors.toList()));
                }

                // 添加分组中的用户
                if (offers.getGroupIds() != null && offers.getGroupIds().length > 0) {
                    // 根据分组ID数组查询用户ID列表
                    List<Long> groupUserIds = sysGroupUserService.selectUserIdsByGroupIds(offers.getGroupIds());
                    if (groupUserIds != null && !groupUserIds.isEmpty()) {
                        userIds.addAll(groupUserIds);
                    }
                }

                // 去重
                userIds = userIds.stream().distinct().collect(Collectors.toList());
            }

            // 如果有用户需要发送邮件
            if (!userIds.isEmpty()) {
                // 获取用户邮箱信息
                List<String> emailAddresses = new ArrayList<>();
                List<String> invalidEmails = new ArrayList<>(); // 记录无效邮箱

                for (Long userId : userIds) {
                    SysUser user = sysUserService.selectUserById(userId);
                    if (user != null && StringUtils.isNotEmpty(user.getEmail())) {
                        // 验证邮箱格式
                        if (isValidEmail(user.getEmail())) {
                            emailAddresses.add(user.getEmail());
                        } else {
                            invalidEmails.add(user.getEmail() + "(用户ID: " + userId + ")");
                        }
                    }
                }

                if (!emailAddresses.isEmpty()) {
                    // 发送邮件
                    sendEmailNotification(emailAddresses, offers);
                    logger.info("成功发送邮件给 {} 个用户", emailAddresses.size());

                    // 记录无效邮箱
                    if (!invalidEmails.isEmpty()) {
                        logger.warn("发现 {} 个无效邮箱地址: {}", invalidEmails.size(), String.join(", ", invalidEmails));
                    }
                } else {
                    logger.warn("没有找到有效的邮箱地址，跳过邮件发送");
                    if (!invalidEmails.isEmpty()) {
                        logger.warn("无效邮箱地址列表: {}", String.join(", ", invalidEmails));
                    }
                }
            } else {
                logger.warn("没有找到需要发送邮件的用户");
            }
        } catch (Exception e) {
            logger.error("发送邮件通知时发生错误", e);
        }
    }

    /**
     * 验证邮箱格式
     *
     * @param email 邮箱地址
     * @return 是否有效
     */
    private boolean isValidEmail(String email) {
        if (StringUtils.isEmpty(email)) {
            return false;
        }
        // 简单的邮箱格式验证
        return email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
    }

    /**
     * 发送邮件通知
     *
     * @param emailAddresses 邮箱地址列表
     * @param offers offer信息
     */
    private void sendEmailNotification(List<String> emailAddresses, Offers offers) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

            // 设置发件人
            helper.setFrom(fromEmail != null ? fromEmail : "203125235@qq.com");

            // 设置收件人（分批发送，避免一次性发送太多）
            if (emailAddresses.size() > 50) {
                // 如果收件人超过50个，分批发送
                sendBatchEmail(helper, emailAddresses, offers);
            } else {
                // 直接发送
                helper.setTo(emailAddresses.toArray(new String[0]));
                sendSingleEmail(helper, offers);
            }

            logger.info("邮件发送成功，收件人数量: {}", emailAddresses.size());
        } catch (Exception e) {
            logger.error("邮件发送失败", e);
            throw new RuntimeException("邮件发送失败: " + e.getMessage(), e);
        }
    }

    /**
     * 分批发送邮件
     */
    private void sendBatchEmail(MimeMessageHelper helper, List<String> emailAddresses, Offers offers)
            throws MessagingException {
        int batchSize = 50; // 每批50个收件人
        for (int i = 0; i < emailAddresses.size(); i += batchSize) {
            int end = Math.min(i + batchSize, emailAddresses.size());
            List<String> batch = emailAddresses.subList(i, end);
            helper.setTo(batch.toArray(new String[0]));
            sendSingleEmail(helper, offers);

            logger.info("已发送邮件批次 {}/{}，该批次收件人数量: {}",
                    (i/batchSize + 1),
                    (emailAddresses.size() + batchSize - 1) / batchSize,
                    batch.size());
        }
    }

    /**
     * 发送单封邮件
     */
    private void sendSingleEmail(MimeMessageHelper helper, Offers offers) throws MessagingException {
        // 设置邮件主题
        String subject = "TEEMO-NEW | Offer "+offers.getOfferId()+"  has been posted!";
        helper.setSubject(subject);

        // 构建邮件内容
        String content = buildEmailContent(offers);
        helper.setText(content, true); // true表示HTML格式

        // 发送邮件
        javaMailSender.send(helper.getMimeMessage());
    }

    /**
     * 构建邮件内容
     *
     * @param offers offer信息
     * @return 邮件内容
     */
    private String buildEmailContent(Offers offers) {
        StringBuilder content = new StringBuilder();
        content.append("<html><body>");
        content.append("<h2>TEEMO-NEW has created/changer an offer  </h2>");
        content.append("<hr/>");
        content.append("<p><strong>Offer Details:</strong></p>");
        content.append("<table border='1' cellpadding='5' cellspacing='0' style='border-collapse: collapse;'>");

        if (StringUtils.isNotEmpty(offers.getOfferName())) {
            content.append("<tr><td><strong>Offer Name:</strong></td><td>").append(offers.getOfferName()).append("</td></tr>");
        }

        if (offers.getPrice() != null) {
            content.append("<tr><td><strong>Price:</strong></td><td>").append(offers.getPrice()).append("</td></tr>");
        }

        if (offers.getQuantity() != null) {
            content.append("<tr><td><strong>Quantity:</strong></td><td>").append(offers.getQuantity()).append("</td></tr>");
        }

        if (offers.getBonus() != null) {
            content.append("<tr><td><strong>Bonus:</strong></td><td>").append(offers.getBonus()).append("</td></tr>");
        }

        if (offers.getExpiresAt() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            content.append("<p><strong>Expires:</strong> ").append(sdf.format(offers.getExpiresAt())).append("</p>");
        }

        if (StringUtils.isNotEmpty(offers.getNote())) {
            content.append("<tr><td><strong>Note:</strong></td><td>").append(offers.getNote().replace("\n", "<br/>")).append("</td></tr>");
        }

        content.append("</table>");
        content.append("<br/>");
        content.append("</body></html>");
        return content.toString();
    }

    /**
     * 删除offers
     */
    @PreAuthorize("@ss.hasPermi('purchase:offers:remove')")
    @Log(title = "offers", businessType = BusinessType.DELETE)
    @DeleteMapping("/{offerIds}")
    public AjaxResult remove(@PathVariable Long[] offerIds)
    {
        return toAjax(offersService.deleteOffersByOfferIds(offerIds));
    }
}
